;
(function(window) {

  const clickoutside = {
    // 初始化指令
    bind(el, binding, vnode) {
      function documentHandler(e) {
        if (el.contains(e.target)) {
          return false;
        }
        if (binding.expression) {
          binding.value(e);
        }
      }

      el.__vueClickOutside__ = documentHandler;
      document.addEventListener('click', documentHandler);
    },
    unbind(el, binding) {
      document.removeEventListener('click', el.__vueClickOutside__);
      delete el.__vueClickOutside__;
    },
  };

  const hlOperationSelect = {
    template: `<div class="hl-operation-select__container"
        :style="{ 'width': selectWidth }"
        :class="[  block ? 'is-block' : '' ]"
        ref="hl-operation-select"
        v-clickoutside="handleClose"
    >
      <div class="hl-operation-select__input-wrap"
           :style="{ 'width': selectWidth }"
           :class="[  type ? 'hl-select-' + type : '' ]"
            @click="handleClickInput"
      >
        <input type="text" autocomplete="off" :placeholder="placeholder" v-model="inputText">
        <span class="icon hl-arrow-right-icon" v-show="arrowDirection == 'right'"></span>
        <span class="icon hl-arrow-down-icon"  v-show="arrowDirection == 'down'"></span>
      </div>

      <div class="hl-operation-select__dropdown"
           :style="{ 'width': selectWidth , 'max-height': selectDropdownHeight + 'px'}" v-if="cascade == false && dropdownIsShow"
      >
        <ul>
          <li class="hl-operation-select__item" :class="{'is-selected':selectedData.indexOf(item.code) > -1 , 'is-checked':item.code == lastSelectedItem }" :data-code="item.code" v-for="(item,index) in data" @click="handleClick(item)">
            <span class="name">{{item.name}}</span>
            <i class="operation-icon icon-Gm-edit"     @click.prevent.stop="handleEdit(item,index,$event)"     @mouseenter.prevent.stop="handleEditMouseenter(item,index,$event)"  @mouseleave.prevent.stop="handleEditMouseleave(item,index,$event)" v-show="edit"></i>
            <i class="operation-icon icon-Gm-delete"   @click.prevent.stop="handleDelete(item,index,$event)" @mouseenter.prevent.stop="handleDeleteMouseenter(item,index,$event)"  @mouseleave.prevent.stop="handleDeleteMouseleave(item,index,$event)" v-show="del"></i>
            <i class="operation-icon icon-Org-account" @click.prevent.stop="handleAdd(item,index,$event)"  @mouseenter.prevent.stop="handleAddMouseenter(item,index,$event)"       @mouseleave.prevent.stop="handleAddMouseleave(item,index,$event)" v-show="add"></i>
          </li>
        </ul>
      </div>

      <div class="hl-operation-select__dropdown"
           :style="{ 'width': selectWidth , 'max-height': selectDropdownHeight + 'px'}" v-if="cascade == true && dropdownIsShow"
      >
        <div class="first-level-wrap" v-for="(item,index) in data">
          <p class="first-name">{{item.name}}</p>
          <ul>
            <li class="hl-operation-select__item" :class="{'is-selected':selectedData.indexOf(item1.code) > -1 , 'is-checked':item1.code == lastSelectedItem }" :data-code="item1.code" v-for="(item1,index1) in item.children" @click="handleClick(item1)">
              <span class="name">{{item1.name}}</span>
              <i class="operation-icon icon-Gm-edit" @click.prevent.stop="handleEdit(item,index,$event)" v-show="edit"></i>
              <i class="operation-icon icon-Gm-delete" @click.prevent.stop="handleDelete(item,index,$event)" v-show="del"></i>
              <i class="operation-icon icon-Org-account" @click.prevent.stop="handleAdd(item,index,$event)" v-show="add"></i>
            </li>
          </ul>
        </div>
      </div>

    </div>`,
    data() {
      return {
        inputText: null,
        lastSelectedItem: null,
        dropdownIsShow: false,
        arrowDirection:'right'
      }
    },
    model: {
      prop: 'selected',
      event: 'on-select-item'
    },
    props: {
      data: {
        type: Array,
        default: () => []
      },
      selected: {
        type: Array,
        default: () => []
      },
      width: {
        type: [String, Number],
        default: 0
      },
      dropdownHeight: {
        type: [String, Number],
        default: 200
      },
      size: {
        type: String,
        default: 'medium'
      },
      type: {
        type: String,
        default: 'primary'
      },
      cascade: {
        type: Boolean,
        default: false
      },
      block: {
        type: Boolean,
        default: false
      },
      isShow: {
        type: Boolean,
        default: false
      },
      add: {
        type: Boolean,
        default: false
      },
      del: {
        type: Boolean,
        default: false
      },
      edit: {
        type: Boolean,
        default: false
      },
      placeholder: {
        type: String,
        default: '请选择'
      }
    },
    directives: {
      clickoutside
    },
    computed: {
      selectWidth() {
        // 如果用户传入 width 值，则优先 width  其次参考 size
        if (this.width == 'auto' || this.width == '100%') return this.width
        if (this.width !== 0) return this.width + 'px'

        if (this.size == 'samll') this.width = '126px'
        if (this.size == 'medium') this.width = '156px'
        if (this.size == 'large') this.width = '310px'

        return this.width
      },
      selectDropdownHeight() {
        return this.dropdownHeight
      },
      selectedData() {
        return this.selected
      },
    },
    watch:{
      selected(val) {
        this.getShowText()
        // this.lastSelectedItem = null
      },
      data() {
        this.getShowText()
        this.lastSelectedItem = null
      },
    },
    created() {
      this.getShowText()
    },
    methods: {
      handleClickInput() {
        this.dropdownIsShow = true
        this.arrowDirection = 'down'
        this.$emit('on-click', event)
      },
      handleClose() {
        this.dropdownIsShow = false
        this.arrowDirection = 'right'
        this.$emit('on-visible-change', false)
      },
      handleClick(item, index) {
        this.singleChoiceType(item)
        this.handleClose()
      },
      mapCodeToName() {
        let tmpNameArr = []
        // 如果为一层数据
        if (this.cascade == false) {
          this.data.forEach((el, i) => {
            if (this.selectedData.indexOf(el.code) > -1) {
              tmpNameArr.push(el['name'])
            }
          })
        }
        // 如果为二层数据
        if (this.cascade == true) {
          this.data.forEach((el, i) => {
            el.children.forEach((el1, i1) => {
              if (this.selectedData.indexOf(el1.code) > -1) {
                tmpNameArr.push(el1['name'])
              }
            })
          })
        }

        return tmpNameArr
      },
      // 选择框显示文本信息
      getShowText() {
        if (this.selected.length == 0) {
          this.inputText = null
          return false
        }

        if (this.selected.length) {
          const showName = this.mapCodeToName()
          if (showName.length) {
            this.inputText = showName.join(';')
          } else {
            this.inputText = this.selected.join(';')
          }
        }

      },
      singleChoiceType(item) {
        const { code } = item
        const positonIndex = this.selectedData.indexOf(code)

        let selectedNameData = []

        if (positonIndex == -1) {
          if (this.selectedData.length == 0) {
            this.selectedData.push(code)
          } else {
            this.selectedData.splice(0, 1, code)
          }
        }

        // 吐出所有选中的数据
        let allSelectedData = []


        console.log(this.selectedData);

        // 如果为一层数据
        if (this.cascade == false) {
          for (var i = 0; i < this.data.length; i++) {
            if (this.data[i].code == this.selectedData[0]) {
              allSelectedData.push(this.data[i])
              selectedNameData.push(this.data[i]['name'])
            }
          }
        }

        // 如果为二层数据
        if (this.cascade == true) {
          for (var i = 0; i < this.data.length; i++) {
            for (var j = 0; j < this.data[i]['children'].length; j++) {
              if (this.data[i]['children'][j]['code'] == this.selectedData[0]) {
                allSelectedData.push(this.data[i]['children'][j])
                selectedNameData.push(this.data[i]['children'][j]['name'])
                break
              }
            }
          }
        }

        if (this.lastSelectedItem == code) {
          this.lastSelectedItem = null
        } else {
          this.lastSelectedItem = code
        }

        console.log(allSelectedData);

        this.inputText = selectedNameData.join()
        this.$emit('on-select-item', this.selectedData)
        this.$emit('on-change', allSelectedData, event)
      },
      handleEdit(item,i,event){
        this.$emit('on-edit-item',item,i,event)
      },
      handleDelete(item,i,event){
        this.$emit('on-delete-item',item,i,event)
      },
      handleAdd(item,i,event){
        this.$emit('on-add-item',item,i,event)
      },

      handleEditMouseenter(item,i,event){
        this.$emit('on-enter-edit-item',item,i,event)
      },
      handleDeleteMouseenter(item,i,event){
        this.$emit('on-enter-delete-item',item,i,event)
      },
      handleAddMouseenter(item,i,event){
        this.$emit('on-enter-add-item',item,i,event)
      },

      handleEditMouseleave(item,i,event){
        this.$emit('on-leave-edit-item',item,i,event)
      },
      handleDeleteMouseleave(item,i,event){
        this.$emit('on-leave-delete-item',item,i,event)
      },
      handleAddMouseleave(item,i,event){
        this.$emit('on-leave-add-item',item,i,event)
      },
    }

  }

  Vue.component('hl-operation-select', hlOperationSelect)

}(window))
